package com.cenxi.ipdemo1.utils.excel;


import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.fastjson2.JSON;
import com.cenxi.ipdemo1.constant.PunchCardConstant;
import com.cenxi.ipdemo1.domain.AttendanceCheckInRecord;
import com.cenxi.ipdemo1.utils.IdGenerator;
import com.cenxi.ipdemo1.utils.RedisCache;
import lombok.EqualsAndHashCode;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.CollectionUtils;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * @author admin
 */
@EqualsAndHashCode(callSuper = true)
@Slf4j
public class ExcelListener extends AnalysisEventListener<Map<Integer, String>> {

	private final List<Map<Integer, String>> readMap = new ArrayList<>();
	/**
	 * 每隔500条存储数据库，然后清理list ，方便内存回收
	 */
	private static final int BATCH_COUNT = 500;
	//Excel表头（列名）数据缓存结构
	private Map<Integer, String> headTitleMap = new HashMap<>();
	private final RedisCache redisCache;


	/**
	 * 每次创建Listener的时候需要把spring管理的类传进来
	 */
	public ExcelListener(RedisCache redisCache){
		this.redisCache = redisCache;
	}


	@Override
	public void invoke(Map<Integer, String> map, AnalysisContext analysisContext) {
		readMap.add(map);
		// 达到对应大小,分析数据
		if (readMap.size() == BATCH_COUNT) {
			// 分析数据
			analyseExcelDetail();
			readMap.clear();
		}
	}

	private void analyseExcelDetail() {
		List<AttendanceCheckInRecord> attendanceCheckInRecords = new ArrayList<>();
		int mark = 0;
		LocalDate clockMonth = LocalDate.now();
		AttendanceCheckInRecord attendanceCheckInRecord = null;
		for (Map<Integer, String> integerStringMap : readMap) {
			if (Objects.nonNull(integerStringMap.get(PunchCardConstant.PUNCH_CARD_DATE))
					&& integerStringMap.get(PunchCardConstant.PUNCH_CARD_DATE).startsWith("考勤日期")) {
				String[] splitTime = integerStringMap.get(PunchCardConstant.PUNCH_CARD_DATE).split("～")[1].split("-");
				clockMonth = LocalDate.of(Integer.parseInt(splitTime[0]), Integer.parseInt(splitTime[1]), Integer.parseInt(splitTime[2]));
			}
			if (Objects.nonNull(integerStringMap.get(PunchCardConstant.PUNCH_CARD_JOB_NUMBER_DESCRIPTION))
					&& integerStringMap.get(PunchCardConstant.PUNCH_CARD_JOB_NUMBER_DESCRIPTION).startsWith("工号")) {
				mark = 1;
				if (Objects.nonNull(attendanceCheckInRecord) && Objects.nonNull(attendanceCheckInRecord.getJobNumber())) {
					attendanceCheckInRecords.add(attendanceCheckInRecord);
				}
				attendanceCheckInRecord = new AttendanceCheckInRecord();
				attendanceCheckInRecord.setId(IdGenerator.generateId());
			}
			if (0 != mark) {
				if (2 == mark) {
					log.info("标记为: {}, 不展示", mark);
					mark++;
					continue;
				}
				log.info("标记为: {}, 数据为: {}", mark, JSON.toJSONString(integerStringMap));
				for (Map.Entry<Integer, String> integerStringEntry : integerStringMap.entrySet()) {
					if (mark == 1) {
						// 记录员工信息
						if (PunchCardConstant.PUNCH_CARD_JOB_NUMBER.equals(integerStringEntry.getKey())) {
							attendanceCheckInRecord.setJobNumber(Long.valueOf(integerStringEntry.getValue()));

						} else if (PunchCardConstant.PUNCH_CARD_NAME.equals(integerStringEntry.getKey())) {
							attendanceCheckInRecord.setName(integerStringEntry.getValue());

						} else if (PunchCardConstant.PUNCH_CARD_DEPARTMENT.equals(integerStringEntry.getKey())) {
							attendanceCheckInRecord.setDepartment(integerStringEntry.getValue());
						}
					}
					if (mark > 1) {
						if (Objects.nonNull(integerStringEntry.getValue())) {
							Map<Integer, String> attendanceCheckInRecordMap = Objects.nonNull(attendanceCheckInRecord.getMap()) ? attendanceCheckInRecord.getMap() : new HashMap<>();
							if (attendanceCheckInRecordMap.containsKey(integerStringEntry.getKey())) {
								String mapVal = attendanceCheckInRecordMap.get(integerStringEntry.getKey()) + "-" + integerStringEntry.getValue().replace("\n", "-");

								attendanceCheckInRecordMap.put(integerStringEntry.getKey(), mapVal);
								attendanceCheckInRecord.setMap(attendanceCheckInRecordMap);
							} else {
								attendanceCheckInRecordMap.put(integerStringEntry.getKey(), integerStringEntry.getValue().replace("\n", "-"));
								attendanceCheckInRecord.setMap(attendanceCheckInRecordMap);
							}
						}
					}
				}
				mark++;
			}
		}
		// 存入缓存
		if (!CollectionUtils.isEmpty(attendanceCheckInRecords)) {
			analyseExcelDetailCache(attendanceCheckInRecords, clockMonth);
		}
	}

	/**
	 * 存入缓存
	 */
	private void analyseExcelDetailCache(List<AttendanceCheckInRecord> attendanceCheckInRecords, LocalDate clockMonth) {
		List<AttendanceCheckInRecord> resList = new ArrayList<>();
		for (AttendanceCheckInRecord attendanceCheckInRecord : attendanceCheckInRecords) {
			for (Map.Entry<Integer, String> integerStringEntry : attendanceCheckInRecord.getMap().entrySet()) {
				for (String clockTime : integerStringEntry.getValue().split("-")) {
					AttendanceCheckInRecord attendance = new AttendanceCheckInRecord();
					attendance.setId(attendanceCheckInRecord.getId());
					attendance.setJobNumber(attendanceCheckInRecord.getJobNumber());
					attendance.setName(attendanceCheckInRecord.getName());
					attendance.setDepartment(attendanceCheckInRecord.getDepartment());
					attendance.setPreDutyDate(LocalDate.of(clockMonth.getYear(), clockMonth.getMonth(), integerStringEntry.getKey()));
					String[] clockTimeSplit = clockTime.split(":");
					attendance.setPreDutyTime(LocalDateTime.of(clockMonth.getYear(), clockMonth.getMonth(), integerStringEntry.getKey(), Integer.parseInt(clockTimeSplit[0]), Integer.parseInt(clockTimeSplit[1])));
					resList.add(attendance);
				}
			}
		}
		log.info("resList: {}", JSON.toJSONString(resList));
		redisCache.setCacheObject("1200:punch", JSON.toJSONString(resList));
	}

	@Override
	public void doAfterAllAnalysed(AnalysisContext context) {
		analyseExcelDetail();
		log.info("---------读取完成---------");
	}


	@Override
	public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {
		headTitleMap = headMap;
	}
}
